package edu.vt.ece.rt.quorum.messsages;

import java.util.concurrent.ConcurrentHashMap;
import org.jgroups.Message;

import edu.vt.ece.rt.QR;
import edu.vt.ece.rt.quorum.ClustersManager;
import edu.vt.ece.rt.quorum.messsages.QMessage.MessageType;
import edu.vt.ece.rt.quorum.messsages.types.Muter;
import edu.vt.ece.rt.quorum.util.ReplyListStore;
import edu.vt.ece.rt.quorum.util.ReplyObjectStore;
import edu.vt.ece.rt.util.Logger.Logger;

/*
 * Task of this class is to Handle any received message in new Thread
 * @author Sudhanshu
 */
		
public class MessageHandler {
	/*
	 * Queue to Maintain the object requests send to different read nodes
	 * Map of String (tx + Id) to ReplyStore
	 */
	public static ConcurrentHashMap<String, ReplyObjectStore> robjectRequestQueue = new ConcurrentHashMap<String, ReplyObjectStore>();
	
	/*
	 * Queue to maintain the object requests send to different write quorum nodes
	 */
	public static ConcurrentHashMap<String, ReplyObjectStore> wobjectRequestQueue = new ConcurrentHashMap<String, ReplyObjectStore>();
	
	/*
	 * Queue to Maintain the List of transactions received on commit Request Success
	 */
	public static ConcurrentHashMap<Long, ReplyListStore> commitRequestQueue = new ConcurrentHashMap<Long, ReplyListStore>();
	
	public static void process(Message msg){		
		Object ob = msg.getObject();
		
		if( !(ob instanceof QMessage)){
			//If not QMessage Must just print the message
	        String line=msg.getSrc() + ": " + msg.getObject();
	        Logger.fetal(line);
			return;
		}
		
		QMessage qOb = (QMessage) ob;
		//Don't process any message if node is muted
		if(QR.getQRStatus() == true){
			return;
		}
		
		if(qOb.type == MessageType.Muter){
			Muter m = (Muter) qOb;
			if(m.reapedNode == ClustersManager.baseClusterId){
				QR.setQRStatus(true);
				Logger.fetal(msg.getSrc() + ":  Muted Me, Good BYE");
				return;				
			}
		}
		
		if(qOb instanceof Runnable){
			//Set the Source of Message
			qOb.setSrcAddr(msg.getSrc());
			
			//Check the Request Type
//			Thread t= new Thread((Runnable) qOb);
//			t.start();
			//Don't create new thread.
			((Runnable) qOb).run();		
			
			//TODO: Remove if no additional processing 
			switch(qOb.type){
				case ReadRequest:
					//Do Smth
					break;
				case ReadResponse:
					//Do Smth
					break;
				case CommitRequest:
					//Do Smth
					break;
				case CommitResponse:
					//Do Smth
					break;
				case CommitConfirm:
					//Do Smth
					break;
				case JoinCluster:
					//Do Smth
					break;
				case PublishObject:
					//Do Smth
					break;
				case MeasureCost:
					//Do Smth
					break;
				case BenchCompletion:
					break;
				case StartNow:
					break;	
				default:
					Logger.error("Unknow Message Type");
			}
		}
	}
}
